#ifndef DATA_H
#define DATA_H

#include <QObject>
#include <QTimer>   //定时器类

// ---- 0       |           2
// -*-  1       |-  T -|    4
// -|_  2                   2
// _|-  3                   2
// |__  4                   4
// __|  5                   4
// 田   6                   1

typedef enum {LEFT = 1, RIGHT, SLOW_DOWN, QUICK_DOWN, BEGIN, END, PAUSE, CHANGE}dir_t;   //左 右 缓慢下 快速下
class Data : public QObject   //数据类
{
    Q_OBJECT
public:
    explicit Data(QObject *parent = 0);
    ~Data();
    void dataInit(void);  //数据初始化
    void createNextBlock(void);   //生成下一个块
    void next2current(void);    //将下一块 --> 当前块
    void getCurrentBlockLimit(void);    //获取当前块的限制
    bool moveDetection(void);   //检测移动时是否碰撞
    bool collisionDetection(void);  //碰撞检测

    bool detectionAddtoBasis(void); //检测是否可添加到根基
    bool detectionMoveIsSure(void); //检测是否可以移动
    void addCurrentBlock2Basis(void);   //将当前块添加到根基
    void deleteALine(void);         //消除 行, 并加分
    void gameEnd(void);             //停止游戏
    void gamePause(void);           //暂停游戏

    bool gameData[20][10];      //游戏界面 x=10 y=20
    bool currentBlock[4][4];    //当前块
    bool nextBlock[4][4];       //下一块
    /* 游戏方块的左上角的坐标(使用该坐标和currentBlock 就可在GUI中绘制出游戏方块) */
    int current_x;
    int current_y;

    bool flag_gameRunning;   //游戏运行标志位 true为运行

    int grade;      //成绩 每消一行得一分

signals:
    void updateUi(void);    //更新UI
    void gameOver(void);     //游戏停止
    void timerStart(int msec);  //打开定时器 (只能通过 信号-槽, 否则会出警告:定时器在别的线程中, 无法打开或关闭)
    void timerStop(void);       //关闭定时器
public slots:
    void slot_gameBegin(void);      //开始游戏
    void slot_timeOut(void);        //定时时间到, 游戏方块下降
    void slot_changeBlcokShape(void);   //改变当前块的形状
    void slot_processKeyEvent(dir_t dir);    //处理按键事件
    void slot_init(void);       //初始化
private:
    int *eachBlockTypes;  //每个块的变形种类
    int currentBlockType[2];       //当前块是哪一类块 [0]为0~6哪一类型块 [1]为该类哪一变形块
    int nextBlockType[2];          //下一块的类型
    int blockTypes; //块的种类
    int timerNum;   //定时器定时时间
    QTimer *timer;  //定时器
    int limit_l[4];    //获取当前块的限制 (根据该限制与墙壁进行碰撞检测)
    int limit_r[4];
    int limit_b[4];
    int flag_quickDown; //快速下降 标志位


    void shape2Data(int *type, bool (*block)[4]);   //根据 type 形状编号, 将数据写入 block中.
    int detectionDeleteALine(void);    //检测是否可以消除一行块

};


#endif // DATA_H
